package com.googlecode.jexnihilo;

import com.googlecode.totallylazy.Sources;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import static com.googlecode.jexnihilo.ContentReplacingSource.replaceContent;
import static com.googlecode.jexnihilo.RenamingSource.renameSources;
import static com.googlecode.totallylazy.FileDestination.fileDestination;
import static com.googlecode.totallylazy.Sources.methods.copyAndClose;
import static com.googlecode.totallylazy.URLs.url;
import static com.googlecode.totallylazy.ZipSource.zipSource;
import static java.lang.String.format;

public class JExNihilo {
	private static final String EXAMPLE_GROUP_ID = "com.example";
	private static final String EXAMPLE_PATH = EXAMPLE_GROUP_ID.replace(".", "/");

	public static void main(String[] args) throws Exception {
		if(fromCommandLine(args))
			System.exit(0);
		System.exit(1);
	}

	public static boolean fromCommandLine(String[] args) throws IOException {
		JExNihilo jExNihilo = new JExNihilo();
		switch (args.length) {
			case 2:
				jExNihilo.letThereBe(url(args[0]), args[1]);
				return true;
			case 3:
				jExNihilo.letThereBe(url(args[0]), args[1], new File(args[2]));
				return true;
			default:
				System.out.println("Usage: java -jar jexnihilo.jar URL GROUP_ID [TARGET_DIRECTORY]");
				return false;
		}
	}

	public void letThereBe(URL zip, String groupId) throws IOException {
		letThereBe(zip, groupId, new File("."));
	}

	public void letThereBe(URL zip, String groupId, File outputDirectory) {
		InputStream zipStream;
		try {
			zipStream = zip.openStream();
		} catch (IOException e) {
			throw new RuntimeException(format("Could not open %1$s", zip), e);
		}
		try {
			copyAndClose(
					source(groupId, zipStream),
					fileDestination(outputDirectory));
		} finally {
			try {
				zipStream.close();
			} catch (IOException e) {
				throw new RuntimeException(format("Could not close %1$s", zip), e);
			}
		}
	}

	private static Sources source(String groupId, InputStream stream) {
		return replaceContent(
				EXAMPLE_GROUP_ID,
				groupId,
				renameSources(
						zipSource(stream),
						EXAMPLE_PATH,
						groupId.replace(".", "/")));
	}

}
